package org.budo.dubbo.protocol.http.page.util;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.validation.constraints.NotNull;

import org.budo.dubbo.protocol.http.util.BudoReflectionUtil;
import org.budo.support.lang.util.ReflectUtil;

import com.alibaba.dubbo.common.utils.CollectionUtils;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

/**
 * 实体结构
 * 
 * @author lmw
 */
public class EntityStructureUtil {
    private static final boolean HAS_NOT_NULL = ReflectUtil.hasClass("javax.validation.constraints.NotNull");

    public static Map<String, Object> typeStructure(Class clazz) {
        String type = clazz.getName();
        Map<String, Object> dataMap = CollectionUtils.toMap("type", type, //
                "simpleName", clazz.getSimpleName());

        if (type.startsWith("java.")) {
            return dataMap;
        }

        ApiModel apiModel = (ApiModel) clazz.getAnnotation(ApiModel.class);
        if (null == apiModel) {
            dataMap.put("ApiModel", "可在类上添加注解 @ApiModel(\"这是一个xxx\")");
        } else {
            String value = apiModel.value();
            dataMap.put("ApiModel", value);
        }

        Map<String, Map<String, Object>> fieldsMap = new HashMap<String, Map<String, Object>>();
        List<Field> fields = BudoReflectionUtil.getAllFields(clazz);
        for (Field field : fields) {
            if (Modifier.isStatic(field.getModifiers())) { // 排除静态属性
                continue;
            }

            Map<String, Object> _fieldMap = fieldsMap.get(field.getName());
            if (null == _fieldMap) {
                boolean notNull = HAS_NOT_NULL && null != field.getAnnotation(NotNull.class);
                String typeLink = GenericTypeHtmlUtil.typeLink(field.getGenericType());

                Map<String, Object> fieldMap = CollectionUtils.toMap("name", field.getName(), //
                        "type", typeLink, //
                        "notnull", notNull);

                ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class);
                if (null == apiModelProperty) {
                    fieldMap.put("ApiModelProperty", "");
                } else {
                    fieldMap.put("ApiModelProperty", apiModelProperty.value());
                }

                fieldsMap.put(field.getName(), fieldMap);
            }
        }

        dataMap.put("fieldList", fieldsMap.values());
        return dataMap;
    }
}